/* =============================================================
 * number-utils.js v1.2.0
 * =============================================================
 * Original written by Ysy
 * =============================================================
 * Date 15/06/2020
 * ============================================================ */
import StringUtils from "@/utils/string-utils";

export default class NumberUtils {
  /**
   * @Author Ysy
   * @Description // 判断变量为字符串
   * @Param str
   * @Date 16:49 2022/6/30
   **/
  static isString( str ) {
    // typeof  对于丰富的对象实例只能返回"Object"字符串  例如：typeof [] 返回的是object
    return str && Object.is( "string", typeof str );
  }

  /**
   * @Author Ysy
   * @Description // 判断变量为数字
   * @Param num
   * @Date 16:50 2022/6/30
   **/
  static isNumber( num ) {
    return num && Object.is( "number", typeof num );
  }

  /**
   * @Author Ysy
   * @Description // TODO
   * @Param obj
   * @Date 16:50 2022/6/30
   **/
  static isObject( obj ) {
    return obj && obj instanceof Object;
  }

  /**
   * @Author Ysy
   * @Description // 判断变量为数组
   * @Param arr
   * @Date 16:50 2022/6/30
   **/
  static isArray( arr ) {
    return arr && arr instanceof Array;
  }

  /**
   * @Author Ysy
   * @Description // 将数字格式化为千分位
   * @Param num
   * @Date 17:16 2022/6/30
   **/
  static numberFormatThousands( num ) {
    if ( !this.isNumber( num ) && !this.isString( num ) ) return num;

    // 保留两位小数
    // num = parseFloat(num);
    // num = num.toFixed(2);

    num = num.toString();

    let int = num.split( "." )[ 0 ];// 取整数部分
    let float = num.split( "." )[ 1 ] || "";// 取小数部分

    int = int.toString().replace( /(\d{1,3})(?=(\d{3})+(?:$|\.))/g, "$1," );// 整数格式化千分位
    float = StringUtils.isEmpty( float ) ? "" : "." + float;

    num = int + float;
    return num;
  }

  /**
   * @Author Ysy
   * @Description // 生成 n-m 之间的随机整数 包含 n和m
   * @Date 17:16 2022/6/30
   * @param n
   * @param m
   **/
  static generateRandomInteger( n, m ) {
    let d = m - n;
    return Math.round( Math.random() * d + n );
  }


  /**
   * @Author Ysy
   * @Description // 生成随机数并转为二进制 截取前4位
   * @Date 17:15 2022/6/30
   **/
  static generateRandom() {
    return ( ( ( 1 + Math.random() ) * 0x10000 ) | 0 ).toString( 16 ).substring( 1 );
  }

  /**
   * @Author Ysy
   * @Description // 生成uuid
   * @Date 17:15 2022/6/30
   **/
  static generateGuid() {
    return ( this.generateRandom() + this.generateRandom() + "-" + this.generateRandom() + "-" + this.generateRandom() + "-" + this.generateRandom() + "-" + this.generateRandom() + this.generateRandom() + this.generateRandom() );
  }

  /**
   * @Author Ysy
   * @Description // 判断数字奇偶
   * @Param num
   * @Date 17:15 2022/6/30
   **/
  static isEvenOrOdd( num ) {
    let boolean = "";

    if ( this.isNumber( num ) ) return boolean;

    boolean = num % 2 === 0 ? "even" : "odd";

    return boolean;
  }

  /**
   * @Author Ysy
   * @Description // 数字转大写汉字
   * @Param num
   * @Date 17:15 2022/6/30
   **/
  static numTransferToChineseChar( num ) {
    if ( !num ) return;

    // 是否负数
    let isNegative = false;
    if ( num < 0 ) {
      num = -num;
      isNegative = true;
    }
    if ( this.isNumber( num ) ) num = num.toString();

    for ( let i = num.length - 1; i >= 0; i-- ) {
      num = num.replace( ",", "" );// 替换money中的“,”
      num = num.replace( " ", "" );// 替换money中的空格
    }
    num = num.replace( "￥", "" );// 替换掉可能出现的￥字符
    // 验证输入的字符是否为数字
    if ( this.isNumber( num ) ) return;

    // ---字符处理完毕，开始转换，转换采用前后两部分分别转换---//
    let part = num.toString().split( "." );
    let newChar = "";
    // 小数点前进行转化
    for ( let i = part[ 0 ].length - 1; i >= 0; i-- ) {
      if ( part[ 0 ].length > 10 ) return "";
      // 若数量超过拾亿单位，提示
      let tmpNewChar = "";
      let perChar = part[ 0 ].charAt( i );
      switch ( perChar ) {
        case "0":
          tmpNewChar = "零" + tmpNewChar;
          break;
        case "1":
          tmpNewChar = "壹" + tmpNewChar;
          break;
        case "2":
          tmpNewChar = "贰" + tmpNewChar;
          break;
        case "3":
          tmpNewChar = "叁" + tmpNewChar;
          break;
        case "4":
          tmpNewChar = "肆" + tmpNewChar;
          break;
        case "5":
          tmpNewChar = "伍" + tmpNewChar;
          break;
        case "6":
          tmpNewChar = "陆" + tmpNewChar;
          break;
        case "7":
          tmpNewChar = "柒" + tmpNewChar;
          break;
        case "8":
          tmpNewChar = "捌" + tmpNewChar;
          break;
        case "9":
          tmpNewChar = "玖" + tmpNewChar;
          break;
      }
      switch ( part[ 0 ].length - i - 1 ) {
        case 0:
          tmpNewChar = tmpNewChar + "元";
          break;
        case 1:
          if ( !Object.is( 0, perChar ) )
            tmpNewChar = tmpNewChar + "拾";
          break;
        case 2:
          if ( !Object.is( 0, perChar ) )
            tmpNewChar = tmpNewChar + "佰";
          break;
        case 3:
          if ( !Object.is( 0, perChar ) )
            tmpNewChar = tmpNewChar + "仟";
          break;
        case 4:
          tmpNewChar = tmpNewChar + "万";
          break;
        case 5:
          if ( !Object.is( 0, perChar ) )
            tmpNewChar = tmpNewChar + "拾";
          break;
        case 6:
          if ( !Object.is( 0, perChar ) )
            tmpNewChar = tmpNewChar + "佰";
          break;
        case 7:
          if ( !Object.is( 0, perChar ) )
            tmpNewChar = tmpNewChar + "仟";
          break;
        case 8:
          tmpNewChar = tmpNewChar + "亿";
          break;
        case 9:
          tmpNewChar = tmpNewChar + "拾";
          break;
      }
      newChar = tmpNewChar + newChar;
    }
    // 小数点之后进行转化
    if ( num.includes( "." ) ) {
      // 小数点之后只能保留两位,系统将自动截段
      if ( part[ 1 ].length > 2 ) part[ 1 ] = part[ 1 ].substr( 0, 2 );

      for ( let i = 0; i < part[ 1 ].length; i++ ) {
        let tmpNewChar = "";
        let perChar = part[ 1 ].charAt( i );
        switch ( perChar ) {
          case "0":
            tmpNewChar = "零" + tmpNewChar;
            break;
          case "1":
            tmpNewChar = "壹" + tmpNewChar;
            break;
          case "2":
            tmpNewChar = "贰" + tmpNewChar;
            break;
          case "3":
            tmpNewChar = "叁" + tmpNewChar;
            break;
          case "4":
            tmpNewChar = "肆" + tmpNewChar;
            break;
          case "5":
            tmpNewChar = "伍" + tmpNewChar;
            break;
          case "6":
            tmpNewChar = "陆" + tmpNewChar;
            break;
          case "7":
            tmpNewChar = "柒" + tmpNewChar;
            break;
          case "8":
            tmpNewChar = "捌" + tmpNewChar;
            break;
          case "9":
            tmpNewChar = "玖" + tmpNewChar;
            break;
        }
        if ( Object.is( 0, i ) )
          tmpNewChar = tmpNewChar + "角";
        if ( Object.is( 1, i ) )
          tmpNewChar = tmpNewChar + "分";
        newChar = newChar + tmpNewChar;
      }
    }
    // 替换所有无用汉字
    while ( newChar.search( "零零" ) !== -1 )
      newChar = newChar.replace( "零零", "零" );
    newChar = newChar.replace( "零亿", "亿" );
    newChar = newChar.replace( "亿万", "亿" );
    newChar = newChar.replace( "零万", "万" );
    newChar = newChar.replace( "零元", "元" );
    newChar = newChar.replace( "零角", "" );
    newChar = newChar.replace( "零分", "" );

    if ( newChar.charAt( newChar.length - 1 ) === "元" || newChar.charAt( newChar.length - 1 ) === "角" ) {
      newChar = newChar + "整";
    }

    if ( isNegative ) {
      newChar = "负" + newChar;
    }

    return newChar;
  }

  /**
   * @Author Ysy
   * @Description // 高精度计算 加法
   * @Date 17:15 2022/6/30
   * @param a
   * @param b
   **/
  static addition( a, b ) {
    let c, d, e;
    try {
      a == null ? c = "0" : c = a.toString().split( "." )[ 1 ].length;
    } catch ( f ) {
      c = 0;
    }
    try {
      b == null ? d = "0" : d = b.toString().split( "." )[ 1 ].length;
    } catch ( f ) {
      d = 0;
    }
    return e = Math.pow( 10, Math.max( c, d ) ), ( this.multiplication( a, e ) + this.multiplication( b, e ) ) / e;
  }

  /**
   * @Author Ysy
   * @Description // 高精度计算 减法
   * @Date 17:14 2022/6/30
   * @param a
   * @param b
   **/
  static subtraction( a, b ) {
    let c, d, e;
    try {
      a == null ? c = "0" : c = a.toString().split( "." )[ 1 ].length;
    } catch ( f ) {
      c = 0;
    }
    try {
      b == null ? d = "0" : d = b.toString().split( "." )[ 1 ].length;
    } catch ( f ) {
      d = 0;
    }
    return e = Math.pow( 10, Math.max( c, d ) ), ( this.multiplication( a, e ) - this.multiplication( b, e ) ) / e;
  }

  /**
   * @Author Ysy
   * @Description // 高精度计算 乘法
   * @Date 17:14 2022/6/30
   * @param a
   * @param b
   **/
  static multiplication( a, b ) {
    let c = 0, d = a == null ? "0" : a.toString(), e = b == null ? "0" : b.toString();

    try {
      c += d.split( "." )[ 1 ].length;
    } catch ( f ) {
    }
    try {
      c += e.split( "." )[ 1 ].length;
    } catch ( f ) {
    }

    return Number( d.replace( ".", "" ) ) * Number( e.replace( ".", "" ) ) / Math.pow( 10, c );
  }

  /**
   * @Author Ysy
   * @Description // 高精度计算 除法
   * @Date 17:14 2022/6/30
   * @param a
   * @param b
   **/
  static division( a, b ) {
    let c, d, e = 0, f = 0;

    try {
      a == null ? e = "0" : e = a.toString().split( "." )[ 1 ].length;
    } catch ( g ) {
    }
    try {
      b == null ? f = "0" : f = b.toString().split( "." )[ 1 ].length;
    } catch ( g ) {
    }

    return c = Number( a.toString().replace( ".", "" ) ), d = Number( b.toString().replace( ".", "" ) ), this.multiplication( c / d, Math.pow( 10, f - e ) );
  }

  /**
   * @Description 编号自增 00001 00002
   * @param num
   * @param numberLength
   * @returns {*}
   */
  static selfIncreasingFunc( num, numberLength ) {
    // 转数据类型，以十进制自增
    num = parseInt( num, 10 ) + 1;
    // 转为字符串
    num = num.toString();
    while ( num.length < numberLength ) {// 当字符串长度小于设定长度时，在前面加0
      num = `0${ num }`;
    }
    // 如果字符串长度超过设定长度只做自增处理。
    return num;
  }

};

